package com.baohua.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.baohua.dao.MenuDao;
import com.baohua.exception.BaohuaSystemException;
import com.baohua.model.Menu;
import com.baohua.service.MenuService;
import com.baohua.util.BeanUtils;

/**
 * MenuService的实现类
 * @author czp
 */

@Service("menuService")
public class MenuServiceImpl implements MenuService {

	/**
	 * 查询所有菜单列表
	 * @return
	 */
	@Override
	public List<Menu> queryMenu() {
		return menuDao.queryMenu("from Menu");
	}

	
	/**
	 * 增加菜单
	 * @param menu 菜单对象
	 */
	@Override
	public void addMenu(Menu menu) throws BaohuaSystemException {
			//将传过来的节点的做为父节点
			String parentNO = menu.getMenuNO();
			
			//获取父节点中有多少子节点, 通过子节点的总数+1,来命名此节点
			long count = countMenuByParentNO(parentNO);
			
			//menuNO的命名规则 : 父节点的menuNO + (count + 1) //不足补0
			String menuNO = parentNO + String.format("%02d", (count + 1));
			//判断此menuNO是否已被命名
			Menu m = queryMenuByMenuNO(menuNO);
			//没有命名
			if(m == null) {
				menu.setMenuNO(menuNO);
				menu.setParentNO(parentNO);
				menu.setLeaf(true);
				
				menuDao.addMenu(menu);
				
				//增加好子节点后, 父节点的路径和是否叶子节点字段要相应的更改为 null 和 false
				//除了根节点
				if(!"0".equals(parentNO)) {
					Menu parentMenu = queryMenuByMenuNO(parentNO);
					parentMenu.setMenuAction(null);
					parentMenu.setLeaf(false);
					
					menuDao.updateMenu(parentMenu);
				}
			}else {
				throw new BaohuaSystemException("菜单编号已经存在");
			}
	}

	/**
	 * 修改菜单
	 * @param menu 菜单对象
	 * @throws BaohuaSystemException 
	 */
	@Override
	public void updateMenu(Menu menu) throws BaohuaSystemException {
		Menu m = queryMenuByMenuNO(menu.getMenuNO());
		//判断menu是否存在
		if(m!=null) {
			//因为menu是通过post提交过来的值, 因为前台没有对MenuId ParentNO赋值, 所以
			// 所以将此两个属性加入到传过来的menu中
			 menu.setMenuId(m.getMenuId());
		     menu.setParentNO(m.getParentNO());
		     System.out.println(m.isLeaf());
		     menu.setLeaf(m.isLeaf());
		     //如果节点名称被修改了, 就要重新拼接节点导航
		     if(!menu.getMenuName().equals(m.getMenuName())) {
		          //如果父节点为根节点, 则导航为节点名称
		    	 if(!"0".equals(m.getParentNO())) {
		    		 //重新拼接节点导航, 取出父节点导航 + 节点名称
				     Menu parentMenu = queryMenuByMenuNO(m.getParentNO());
					 String menuFullPath = parentMenu.getMenuFullPath() + ">" + menu.getMenuName();
					 menu.setMenuFullPath(menuFullPath);
		    	 }else {
		    		 menu.setMenuFullPath(menu.getMenuName());
		    	 }
		     }
			//如果修改的数据发生变化就进行修改
			if(!BeanUtils.compareObject(m, menu)){
				    BeanUtils.copyProperty(menu, m);
				  //BeanUtils不拷贝集合类
				    m.setRoles(menu.getRoles());
			        menuDao.updateMenu(m);
			        
			        //相应更改子节点的导航
			        List<Menu> list = queryMenuByParentNO(m.getMenuNO());
			        for(Menu menu1 : list) {
			        	Menu childMenu = menu1;
			        	childMenu.setMenuFullPath(m.getMenuFullPath() + ">" + childMenu.getMenuName());
			        	menuDao.updateMenu(childMenu);
		        }
	        }
		}else {
			throw new BaohuaSystemException("不存在此菜单");
		}
	}
	

	/**
	 * 删除菜单(支持删除父菜单时, 子菜单也相应删除)
	 * @param menu 菜单对象
	 */
	@Override
	public void delMenu(String menuNO) throws BaohuaSystemException {
		Menu menu = menuDao.queryMenuByMenuNO(menuNO);
		//判断menu是否存在
		if(menu != null) {
			//查询出此节点及以下的子节点
			List<Menu> list = menuDao.queryMenu("from Menu m where m.menuNO like '" + menuNO + "%'");
			for(Menu m : list) {
				menuDao.delMenu(m);
			}
		}else {
			throw new BaohuaSystemException("不存在此菜单");
		}
	}

	
	/**
	 * 统计父菜单下一级子菜单的个数, 便于对menuNO赋值
	 * @param ParentNO
	 * @return
	 */
	private long countMenuByParentNO(String parentNO) {
		long count = menuDao.countMenu("select count(*) from Menu m where m.parentNO='" + parentNO + "'");
		return count;
	}
	
	/**
	 * 查询同一个父类节点为parentNO的子节点
	 * @param parentNO
	 * @return
	 */
	public List<Menu> queryMenuByParentNO(String parentNO) {
		List<Menu> list =  menuDao.queryMenu("from Menu m where m.parentNO like '" + parentNO + "%'");
		return list;
	}

	/**
	 * 根据menuNO进行查询菜单
	 * @param menuNO
	 * @return
	 */
	@Override
	public Menu queryMenuByMenuNO(String menuNO) {
		Menu menu = menuDao.queryMenuByMenuNO(menuNO);
		return menu;
	}
	
private MenuDao menuDao;
	
	public MenuDao getMenuDao() {
		return menuDao;
	}

	@Resource(name="menuDao")
	public void setMenuDao(MenuDao menuDao) {
		this.menuDao = menuDao;
	}

}
